package cn.com.dcsgo.service.impl;

import cn.com.dcsgo.domain.SysRoleMenu;
import cn.com.dcsgo.dto.PageDTO;
import cn.com.dcsgo.dto.SysRoleAddDTO;
import cn.com.dcsgo.dto.SysRoleQueryDTO;
import cn.com.dcsgo.dto.SysRoleUpdateDTO;
import cn.com.dcsgo.exception.BusinessException;
import cn.com.dcsgo.mapper.SysRoleMenuMapper;
import cn.com.dcsgo.utils.AuthUtil;
import cn.com.dcsgo.vo.SysRoleVO;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.com.dcsgo.domain.SysRole;
import cn.com.dcsgo.service.SysRoleService;
import cn.com.dcsgo.mapper.SysRoleMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 针对表【sys_role(角色)】的数据库操作Service实现
 *
 * @author Dcsgo
 * @since 2025-09-22 15:09:11
 */
@Slf4j
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole>
        implements SysRoleService {
    @Resource
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public List<SysRole> getList() {
        // 所有角色列表
        List<SysRole> sysRoles = getBaseMapper().selectList(null);
        // shopId == 1 为超级管理员(超级店铺、顶级店铺)可查看所有角色除此之外的用户只能查看非管理员(roleId!=1)的角色
        if (AuthUtil.getShopId() != 1) {
            sysRoles = sysRoles.stream().filter(sysRole -> !sysRole.getRoleId().equals(1L)).collect(Collectors.toList());
        }
        return sysRoles;
    }

    @Override
    public Page<SysRole> getPage(PageDTO pageDTO, SysRoleQueryDTO sysRoleQueryDTO) {
        Page<SysRole> page = new Page<>(pageDTO.getCurrent(), pageDTO.getSize());
        return getBaseMapper().selectPage(page,
                new LambdaQueryWrapper<SysRole>()
                        .like(StringUtils.hasText(sysRoleQueryDTO.getRoleName()), SysRole::getRoleName, sysRoleQueryDTO.getRoleName())
                        .orderByAsc(SysRole::getCreateTime)
        );
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public int save(SysRoleAddDTO sysRoleAddDTO) {
        SysRole sysRole = new SysRole();
        BeanUtil.copyProperties(sysRoleAddDTO, sysRole);
        sysRole.setCreateTime(new Date());
        sysRole.setCreateUserId(AuthUtil.getUserId());
        int row = baseMapper.insert(sysRole);
        if (!CollectionUtils.isEmpty(sysRoleAddDTO.getMenuIdList())) {
            // 保存角色与菜单(权限)关联关系
            //TODO: 当角色关联的权限较多时使用批量插入
            for (Long menuId : sysRoleAddDTO.getMenuIdList()) {
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setMenuId(menuId);
                sysRoleMenu.setRoleId(sysRole.getRoleId());
                row += sysRoleMenuMapper.insert(sysRoleMenu);
            }
        }
        log.debug("save 受影响的行数:{}", row);
        return row;
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public int remove(List<Long> roleIds) {
        if (roleIds.contains(1L)) {
            throw new BusinessException("管理员角色不能删除");
        }
        int row = baseMapper.deleteBatchIds(roleIds);
        // 删除角色与权限（菜单）的关联关系（多个角色）
        row += sysRoleMenuMapper.delete(
                new LambdaQueryWrapper<SysRoleMenu>()
                        .in(SysRoleMenu::getRoleId, roleIds)
        );
        log.debug("remove 受影响的行数:{}", row);
        return row;
    }

    @Override
    public SysRoleVO getRoleInfo(Long roleId) {
        SysRole sysRole = baseMapper.selectById(roleId);
        SysRoleVO sysRoleVO = new SysRoleVO();
        BeanUtil.copyProperties(sysRole, sysRoleVO);
        List<SysRoleMenu> roleMenuList = sysRoleMenuMapper.selectList(
                new LambdaQueryWrapper<SysRoleMenu>()
                        .eq(SysRoleMenu::getRoleId, roleId)
        );
        List<Long> menuIdList = roleMenuList.stream().map(SysRoleMenu::getMenuId).toList();
        sysRoleVO.setMenuIdList(menuIdList);
        return sysRoleVO;
    }

    @Override
    public int update(SysRoleUpdateDTO sysRoleUpdateDTO) {
        SysRole sysRole = new SysRole();
        BeanUtil.copyProperties(sysRoleUpdateDTO, sysRole);
        int row = baseMapper.updateById(sysRole);
        // 删除角色与权限（菜单）的关联关系 （注意清空角色权限的情况）
        row += sysRoleMenuMapper.delete(
                new LambdaQueryWrapper<SysRoleMenu>()
                        .eq(SysRoleMenu::getRoleId, sysRoleUpdateDTO.getRoleId())
        );
        if (!CollectionUtils.isEmpty(sysRoleUpdateDTO.getMenuIdList())) {
            // 插入新的角色与权限（菜单）的关联关系
            for (Long menuId : sysRoleUpdateDTO.getMenuIdList()) {
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setMenuId(menuId);
                sysRoleMenu.setRoleId(sysRoleUpdateDTO.getRoleId());
                row += sysRoleMenuMapper.insert(sysRoleMenu);
            }
        }
        log.debug("update 受影响的行数:{}", row);
        return row;
    }
}




